﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using V8.Net;
using DreamSpace.Net.ScriptEngines;

namespace DreamSpace.Net
{
    public partial interface IServerHost<out TScriptEngine>
    {
        /// <summary>
        /// Adds a request to be executed within a messaging queue. The request can be to execute a function, or trigger a named event.
        /// <para>Example function call-back: queueMessage(MessageType.CallFunction, myFunction, arguments...); </para>
        /// <para>Example named event call: queueMessage(MessageType.SendMessage, ""); </para>
        /// </summary>
        /// <param name="type"></param>
        /// <param name="data"></param>
        void QueueMessage(MessageType type, params object[] data);

        /// <summary>
        /// Triggers all functions registered to listen for the specified message (a message is just a string of text that event functions are waiting for).
        /// This function is a simplified way of calling 'queueMessage()'.
        /// </summary>
        /// <param name="message">The message to send.</param>
        void SendMessage(string message);

        /// <summary>
        /// Triggers the specified function after the given number of milliseconds.
        /// Although commonly known, this function is not part of the JavaScript standards, but is included for compatibility purposes, and behaves the same way.
        /// </summary>
        Timer SetTimeout(Action function, int milliseconds);

        /// <summary>
        /// Triggers the specified function in the given interval (in milliseconds).
        /// Although commonly known, this function is not part of the JavaScript standards, but is included for compatibility purposes, and behaves the same way.
        /// </summary>
        void ClearTimeout(Timer timer);

        /// <summary>
        /// Triggers the specified function in the given interval (in milliseconds).
        /// Although commonly known, this function is not part of the JavaScript standards, but is included for compatibility purposes, and behaves the same way.
        /// </summary>
        Timer SetInterval(Action function, int milliseconds);

        /// <summary>
        /// Triggers the specified function in the given interval (in milliseconds).
        /// Although commonly known, this function is not part of the JavaScript standards, but is included for compatibility purposes, and behaves the same way.
        /// </summary>
        void ClearInterval(Timer timer);
    }

    
    public partial class ServerHost<TScriptEngine> // This class part holds the JavaScript environment function mappings.
    {
        /// <summary>
        /// Adds a request to be executed within a messaging queue. The request can be to execute a function, or trigger a named event.
        /// <para>Example function call-back: queueMessage(MessageType.CallFunction, myFunction, arguments...); </para>
        /// <para>Example named event call: queueMessage(MessageType.SendMessage, ""); </para>
        /// </summary>
        /// <param name="type"></param>
        /// <param name="data"></param>
        [ScriptMember("queueMessage")]
        public void QueueMessage(MessageType type, params object[] data)
        {
            lock (_Messages)
            {
                _Messages.Enqueue(new Message(type, data));
            }
        }

        /// <summary>
        /// Triggers all functions registered to listen for the specified message (a message is just a string of text that event functions are waiting for).
        /// This function is a simplified way of calling 'queueMessage()'.
        /// </summary>
        /// <param name="message">The message to send.</param>
        [ScriptMember("sendMessage")]
        public void SendMessage(string message)
        {
            QueueMessage(MessageType.SendMessage, message);
        }

        /// <summary>
        /// Triggers the specified function after the given number of milliseconds.
        /// Although commonly known, this function is not part of the JavaScript standards, but is included for compatibility purposes, and behaves the same way.
        /// </summary>
        [ScriptMember("setTimeout")]
        public Timer SetTimeout(Action function, int milliseconds)
        {
            Timer timer = null;
            timer = new Timer((s) => { QueueMessage(MessageType.CallFunction, function); timer.Dispose(); }, null, milliseconds, Timeout.Infinite);
            return timer;
        }

        /// <summary>
        /// Triggers the specified function in the given interval (in milliseconds).
        /// Although commonly known, this function is not part of the JavaScript standards, but is included for compatibility purposes, and behaves the same way.
        /// </summary>
        [ScriptMember("clearTimeout")]
        public void ClearTimeout(Timer timer)
        {
            timer.Dispose();
        }

        /// <summary>
        /// Triggers the specified function in the given interval (in milliseconds).
        /// Although commonly known, this function is not part of the JavaScript standards, but is included for compatibility purposes, and behaves the same way.
        /// </summary>
        [ScriptMember("setInterval")]
        public Timer SetInterval(Action function, int milliseconds)
        {
            Timer timer = null;
            timer = new Timer((s) => { QueueMessage(MessageType.CallFunction, function); }, null, milliseconds, 0);
            return timer;
        }

        /// <summary>
        /// Triggers the specified function in the given interval (in milliseconds).
        /// Although commonly known, this function is not part of the JavaScript standards, but is included for compatibility purposes, and behaves the same way.
        /// </summary>
        [ScriptMember("clearInterval")]
        public void ClearInterval(Timer timer)
        {
            timer.Dispose();
        }
    }
}
